package com.avalon.core.table;

import com.avalon.core.alias.AbstractAliasSupport;
import com.avalon.core.condition.Condition;
import com.avalon.core.context.Context;
import com.avalon.core.db.AvalonPreparedStatement;
import com.avalon.core.enums.ServiceOperateEnum;
import com.avalon.core.exception.AvalonException;
import com.avalon.core.exception.FieldCheckException;
import com.avalon.core.field.Field;
import com.avalon.core.field.IFieldFormat;
import com.avalon.core.model.Record;
import com.avalon.core.model.*;
import com.avalon.core.select.builder.SelectBuilderList;
import com.avalon.core.service.AbstractService;
import com.avalon.core.util.FieldValue;
import com.avalon.core.util.ObjectUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.event.ApplicationReadyEvent;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional;

import javax.validation.constraints.NotNull;
import java.lang.reflect.Type;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;


@Slf4j
@Transactional(isolation = Isolation.READ_COMMITTED, rollbackFor = Exception.class)
public abstract class AbstractTableManageService implements ITableManage, ApplicationListener<ApplicationEvent> {
    @Autowired
    private Context context;

    @Override
    public ITableService getFirstTableService() {
        TableServiceList tableServices = getTableServiceList();
        if (ObjectUtils.isNull(tableServices) || tableServices.size() == 0)
            throw new FieldCheckException("未设置服务");
        return tableServices.get(0);
    }

    @Override
    public Boolean getNeedDefaultField() {
        return false;
    }

    @Override
    public Boolean getNeedDefaultKeyField() {
        return false;
    }

    @Override
    public String getBaseName() {
        return getContext().getBaseName();
    }

    @Override
    public Field getNameField() {
        ITableService firstTableService = getFirstTableService();
        return firstTableService.getNameField();
    }

    @Override
    public FieldHashMap getFieldMap() {
        ITableService firstTableService = getFirstTableService();
        return firstTableService.getFieldMap();
    }

    @Override
    public FieldHashMap getRelationFieldMap() {
        ITableService firstTableService = getFirstTableService();
        return firstTableService.getRelationFieldMap();
    }

    @Override
    public FieldHashMap getNotRelationAndPrimaryKeyFieldMap() {
        ITableService firstTableService = getFirstTableService();
        return firstTableService.getNotRelationAndPrimaryKeyFieldMap();
    }

    @Override
    public Record select(List<String> fields, Condition condition) throws AvalonException {
        Record result = new Record();
        for (ITableService iTableService : getTableServiceList()) {
            result.join(iTableService.select(fields, condition));
        }
        return result;
    }

    @Override
    public Record selectWithObject(List<String> fields, Condition condition) throws AvalonException {
        Record result = new Record();
        for (ITableService iTableService : getTableServiceList()) {
            result.join(iTableService.selectWithObject(fields, condition));
        }
        return result;
    }

    @Override
    public Record selectWithObject(String fields, Condition condition) throws AvalonException {
        Record result = new Record();
        for (ITableService iTableService : getTableServiceList()) {
            result.join(iTableService.selectWithObject(fields, condition));
        }
        return result;
    }

    @Override
    public PageInfo selectPageWithObjectExtend(PageParam pageParam,
                                               String fields,
                                               String order,
                                               Boolean isDistinct,
                                               List<PageConditionHigh> conditions) throws AvalonException {
        if (ObjectUtils.isEmpty(conditions)) {
            return selectPageWithObject(pageParam, fields, order, isDistinct);
        } else {
            return selectPageWithObject(pageParam, fields, order, isDistinct,
                    getConditionByHighListCondition(conditions));
        }
    }

    @Override
    public PageInfo selectPageWithObject(PageParam pageParam,
                                         String fields,
                                         String order,
                                         Boolean isDistinct) throws AvalonException {

        return selectPageWithObject(pageParam, fields, order, isDistinct, null);

    }

    @Override
    public PageInfo selectPageWithObject(PageParam pageParam,
                                         String fields,
                                         String order,
                                         Boolean isDistinct,
                                         Condition condition) throws AvalonException {
        SelectBuilderList selectBuilderList = new SelectBuilderList();
        for (ITableService iTableService : getTableServiceList()) {
            selectBuilderList.add(iTableService.selectAllRecord(fields, condition, order));
        }
        StringBuilder tablePageSql = selectBuilderList.getTablePageSql(pageParam);

        Integer total = getContext().getJdbcTemplate()
                .selectCount(tablePageSql,
                        selectBuilderList.getTableFieldValueStatement());


        StringBuilder sql = selectBuilderList.getTablePageSql(pageParam);

        AvalonPreparedStatement avalonPrepareStatement = createAvalonPrepareStatement(sql,
                selectBuilderList.getTableFieldValueStatement());
        Record record = getContext().getJdbcTemplate().selectObject(avalonPrepareStatement,
                selectBuilderList.get(0));

        return new PageInfo(record, total, pageParam.getPageNum(), pageParam.getPageSize());
    }

    @Override
    public Record select(List<String> fields, Condition condition, String order) throws AvalonException {
        Record result = new Record();
        for (ITableService iTableService : getTableServiceList()) {
            result.join(iTableService.select(fields, condition, order));
        }
        return result;
    }

    @Override
    public Record select(List<String> fields) throws AvalonException {
        Record result = new Record();
        for (ITableService iTableService : getTableServiceList()) {
            result.join(iTableService.select(fields));
        }
        return result;
    }

    @Override
    public Record select(String fields) throws AvalonException {
        Record result = new Record();
        for (ITableService iTableService : getTableServiceList()) {
            result.join(iTableService.select(fields));
        }
        return result;
    }

    @Override
    public Record select(Condition condition) throws AvalonException {
        Record result = new Record();
        for (ITableService iTableService : getTableServiceList()) {
            result.join(iTableService.select(condition));
        }
        return result;
    }

    @Override
    public Record select(String fields, List<PageConditionHigh> pageConditionHighList) {
        Record result = new Record();
        for (ITableService iTableService : getTableServiceList()) {
            result.join(iTableService.select(fields, pageConditionHighList));
        }
        return result;
    }

    @Override
    public Record select(String fields, Condition condition) throws AvalonException {
        Record result = new Record();
        for (ITableService iTableService : getTableServiceList()) {
            result.join(iTableService.select(fields, condition));
        }
        return result;
    }

    @Override
    public Record select(String fields, Condition condition, String orderBy) throws AvalonException {
        Record result = new Record();
        for (ITableService iTableService : getTableServiceList()) {
            result.join(iTableService.select(fields, condition, orderBy));
        }
        return result;
    }

    @Override
    public Record selectList(String fields, Map<String, Object> condition) throws AvalonException {
        Record result = new Record();
        for (ITableService iTableService : getTableServiceList()) {
            result.join(iTableService.selectList(fields, condition));
        }
        return result;
    }

    @Override
    public Integer selectCount(String fields, Condition condition, String order) throws AvalonException {
        Integer count = 0;
        for (ITableService iTableService : getTableServiceList()) {

            count += iTableService.selectCount(fields, condition, order);
        }
        return count;
    }

    @Override
    public Integer selectCount(String fields, Condition condition) throws AvalonException {
        Integer count = 0;
        for (ITableService iTableService : getTableServiceList()) {

            count += iTableService.selectCount(fields, condition);
        }
        return count;
    }

    @Override
    public Integer selectCount(Condition condition) throws AvalonException {
        Integer count = 0;
        for (ITableService iTableService : getTableServiceList()) {

            count += iTableService.selectCount(condition);
        }
        return count;
    }

    @Override
    public PageInfo selectPage(PageParam pageParam,
                               String fields,
                               String order,
                               Boolean isDistinct,
                               Condition condition) throws AvalonException {

        SelectBuilderList selectBuilderList = new SelectBuilderList();
        for (ITableService iTableService : getTableServiceList()) {
            selectBuilderList.add(iTableService.selectAllRecord(fields, condition, order));
        }
        StringBuilder tablePageSql = selectBuilderList.getTablePageSql(pageParam);

        Integer total = getContext().getJdbcTemplate()
                .selectCount(tablePageSql,
                        selectBuilderList.getTableFieldValueStatement());


        StringBuilder sql = selectBuilderList.getTablePageSql(pageParam);

        AvalonPreparedStatement avalonPrepareStatement = createAvalonPrepareStatement(sql,
                selectBuilderList.getTableFieldValueStatement());
        Record record = getContext().getJdbcTemplate().select(avalonPrepareStatement,
                selectBuilderList.get(0));

        return new PageInfo(record, total, pageParam.getPageNum(), pageParam.getPageSize());
    }

    @Override
    public PageInfo selectPage(PageParam pageParam,
                               String fields,
                               String order,
                               Boolean isDistinct) throws AvalonException {
        return selectPage(pageParam, fields, order, isDistinct, null);
    }

    @Override
    public PageInfo selectPageNormal(PageParam pageParam,
                                     String fields,
                                     Map<String, Object> condition,
                                     String order,
                                     Boolean isDistinct) throws AvalonException {
        if (ObjectUtils.isEmpty(condition)) {
            return selectPage(pageParam, fields, order, null);
        }

        Condition con = null;
        for (Map.Entry<String, Object> keyValue : condition.entrySet()) {
            if (ObjectUtils.isEmpty(keyValue.getValue())) {
                continue;
            }
            Field field = getField(keyValue.getKey());
            Object value = keyValue.getValue();
            if (field instanceof IFieldFormat) {
                value = field.parse(value);
            }
            con = Condition.andCondition(con, Condition.equalCondition(keyValue.getKey(), value));
        }

        return selectPage(pageParam, fields, order, isDistinct, con);
    }

    @Override
    public PageInfo selectPageCondition(PageParam pageParam,
                                        String fields,
                                        String order,
                                        Boolean isDistinct,
                                        List<PageCondition> conditions) throws AvalonException {
        if (ObjectUtils.isEmpty(conditions)) {
            return selectPage(pageParam, fields, null, isDistinct);
        } else {

            Condition x = null;
            for (Condition condition : conditions) {
                if (ObjectUtils.isEmpty(condition.getValue())) {
                    continue;
                }
                condition = condition.convertAdapterCondition();
                condition.parse(getService());
                if (ObjectUtils.isNull(x)) {
                    x = condition;
                } else {
                    x = x.andCondition(condition);
                }
            }

            return selectPage(pageParam, fields, order, isDistinct, x);
        }
    }

    @Override
    public PageInfo selectPageConditionHigh(PageParam pageParam,
                                            String fields,
                                            String order,
                                            Boolean isDistinct,
                                            List<PageConditionHigh> conditions) throws AvalonException {

        Condition condition = getConditionByHighListCondition(conditions);

        return selectPage(pageParam, fields, order, isDistinct, condition);
    }

    @Override
    public Condition getConditionByHighListCondition(List<PageConditionHigh> conditions) {
        return getFirstTableService().getConditionByHighListCondition(conditions);
    }

    @Override
    public RecordRow selectOne(String fields, Object id) throws AvalonException {
        for (ITableService iTableService : getTableServiceList()) {
            RecordRow recordRow = iTableService.selectOne(fields, id);
            if (ObjectUtils.isNotNull(recordRow) && !recordRow.isEmpty()) {
                return recordRow;
            }
        }
        return new RecordRow();
    }

    @Override
    public RecordRow selectOne(List<String> fieldList, Integer id) throws AvalonException {
        for (ITableService iTableService : getTableServiceList()) {
            RecordRow recordRow = iTableService.selectOne(fieldList, id);
            if (ObjectUtils.isNotNull(recordRow) && !recordRow.isEmpty()) {
                return recordRow;
            }
        }
        return new RecordRow();
    }

    @Override
    public RecordRow selectOne(Condition condition, List<String> fieldList) throws AvalonException {
        for (ITableService iTableService : getTableServiceList()) {
            RecordRow recordRow = iTableService.selectOne(condition, fieldList);
            if (ObjectUtils.isNotNull(recordRow) && !recordRow.isEmpty()) {
                return recordRow;
            }
        }
        return new RecordRow();
    }

    @Override
    public RecordRow selectOneNoLevel(List<String> fieldList, Condition condition, String order) throws AvalonException {
        for (ITableService iTableService : getTableServiceList()) {
            RecordRow recordRow = iTableService.selectOneNoLevel(fieldList, condition, order);
            if (ObjectUtils.isNotNull(recordRow) && !recordRow.isEmpty()) {
                return recordRow;
            }
        }
        return new RecordRow();
    }

    @Override
    public RecordRow selectOneNoLevel(String fields, Condition condition, String order) throws AvalonException {
        for (ITableService iTableService : getTableServiceList()) {
            RecordRow recordRow = iTableService.selectOneNoLevel(fields, condition, order);
            if (ObjectUtils.isNotNull(recordRow) && !recordRow.isEmpty()) {
                return recordRow;
            }
        }
        return new RecordRow();
    }

    @Override
    public RecordRow selectOneNoLevel(String fields, List<PageConditionHigh> conditions, String order) throws AvalonException {
        for (ITableService iTableService : getTableServiceList()) {
            RecordRow recordRow = iTableService.selectOneNoLevel(fields, conditions, order);
            if (ObjectUtils.isNotNull(recordRow) && !recordRow.isEmpty()) {
                return recordRow;
            }
        }
        return new RecordRow();
    }

    @Override
    public AvalonPreparedStatement createAvalonPrepareStatement(StringBuilder sql, FieldValueStatement valueStatement) {
        ITableService firstTableService = getFirstTableService();
        return firstTableService.createAvalonPrepareStatement(sql, valueStatement);
    }

    @Override
    public RecordRow selectOne(String fields, Condition condition) throws AvalonException {
        for (ITableService iTableService : getTableServiceList()) {
            RecordRow recordRow = iTableService.selectOne(fields, condition);
            if (ObjectUtils.isNotNull(recordRow) && !recordRow.isEmpty()) {
                return recordRow;
            }
        }
        return new RecordRow();
    }

    @Override
    public RecordRow selectOne(Integer id) throws AvalonException {
        for (ITableService iTableService : getTableServiceList()) {
            RecordRow recordRow = iTableService.selectOne(id);
            if (ObjectUtils.isNotNull(recordRow) && !recordRow.isEmpty()) {
                return recordRow;
            }
        }
        return new RecordRow();
    }

    @Override
    public RecordRow selectOne(Integer id, List<Field> fieldList) throws AvalonException {
        for (ITableService iTableService : getTableServiceList()) {
            RecordRow recordRow = iTableService.selectOne(id, fieldList);
            if (ObjectUtils.isNotNull(recordRow) && !recordRow.isEmpty()) {
                return recordRow;
            }
        }
        return new RecordRow();
    }

    @Override
    public RecordRow selectOne(Integer id, Field... fields) throws AvalonException {
        for (ITableService iTableService : getTableServiceList()) {
            RecordRow recordRow = iTableService.selectOne(id, fields);
            if (ObjectUtils.isNotNull(recordRow) && !recordRow.isEmpty()) {
                return recordRow;
            }
        }
        return new RecordRow();
    }

    @Override
    public RecordRow selectOne(Condition condition) throws AvalonException {
        for (ITableService iTableService : getTableServiceList()) {
            RecordRow recordRow = iTableService.selectOne(condition);
            if (ObjectUtils.isNotNull(recordRow) && !recordRow.isEmpty()) {
                return recordRow;
            }
        }
        return new RecordRow();
    }

    @Override
    public Integer delete(Object id) throws AvalonException {
        for (ITableService iTableService : getTableServiceList()) {
            Integer delete = iTableService.delete(id);
            if (!delete.equals(0)) return delete;
        }
        return 0;
    }

    @Override
    public Integer delete(Condition condition, String serviceName) throws AvalonException {
        Integer deleteCount = 0;
        for (ITableService iTableService : getTableServiceList()) {
            deleteCount += iTableService.delete(condition, serviceName);
        }
        return deleteCount;
    }

    @Override
    public Integer delete(RecordRow row) throws AvalonException {
        ITableService firstTableService = getFirstTableService();
        return delete(firstTableService.getPrimaryKeyValue(row));
    }

    @Override
    public Integer deleteMulti(List<Integer> ids) throws AvalonException {
        Integer deleteCount = 0;
        for (Integer id : ids) {
            for (ITableService iTableService : getTableServiceList()) {
                deleteCount += iTableService.delete(id);
            }
        }
        return deleteCount;
    }

    @Override
    public Integer deleteMulti(Record record) throws AvalonException {
        Integer deleteCount = 0;
        for (RecordRow recordRow : record) {
            deleteCount += delete(recordRow);
        }
        return deleteCount;
    }

    /**
     * 获取可以插入的服务 均衡负载
     *
     * @return recordRow
     */
    protected abstract ITableService getBalanceService(RecordRow recordRow);

    @Override
    public PrimaryKey insert(RecordRow recordRow) throws AvalonException {
        ITableService balanceService = getBalanceService(recordRow);
        return balanceService.insert(recordRow);
    }

    @Override
    public List<Object> insertMulti(Record record) throws AvalonException {

        List<Object> objs = new ArrayList<>();
        for (RecordRow recordRow : record) {
            objs.add(insert(recordRow));
        }
        return objs;
    }

    @Override
    public Integer update(RecordRow recordRow, Condition condition) throws AvalonException {
        Integer updateCount = 0;
        for (ITableService iTableService : getTableServiceList()) {
            updateCount += iTableService.update(recordRow, condition);
        }
        return updateCount;
    }

    @Override
    public Integer update(RecordRow recordRow) throws AvalonException {
        Integer updateCount = 0;
        for (ITableService iTableService : getTableServiceList()) {
            updateCount += iTableService.update(recordRow);
        }
        return updateCount;
    }

    @Override
    public Integer updateMulti(Record record) throws AvalonException {
        Integer updateCount = 0;
        for (RecordRow recordRow : record) {
            updateCount += update(recordRow);
        }
        return updateCount;
    }

    @Override
    public Object getPrimaryKeyValue(RecordRow row) {
        ITableService firstTableService = getFirstTableService();
        return firstTableService.getPrimaryKeyValue(row);
    }

    @Override
    public String getServiceName() {
        return null;
    }

    @Override
    public String getServiceTableName() {
        return null;
    }

    @Override
    public String getPrimaryKeyName() {
        ITableService firstTableService = getFirstTableService();
        return firstTableService.getPrimaryKeyName();
    }

    @Override
    public Type getPrimaryKeyType() {
        ITableService firstTableService = getFirstTableService();
        return firstTableService.getPrimaryKeyType();
    }

    @Override
    public List<String> getAllFieldName() {
        ITableService firstTableService = getFirstTableService();
        return firstTableService.getAllFieldName();
    }

    @Override
    public void createTable() {
        for (ITableService iTableService : getTableServiceList()) {
            iTableService.createTable();
        }
    }

    @Override
    public void dropTable() {
        for (ITableService iTableService : getTableServiceList()) {
            iTableService.dropTable();
        }
    }

    @Override
    public RecordRow getDefaultValueAll() {
        ITableService firstTableService = getFirstTableService();
        return firstTableService.getDefaultValueAll();
    }

    @Override
    public FieldHashMap getIsRequiredAll() {
        ITableService firstTableService = getFirstTableService();
        return firstTableService.getIsRequiredAll();
    }

    @Override
    public String getAlias(AbstractAliasSupport abstractAliasSupport) {
        return null;
    }

    @Override
    public FieldValue getSumFieldValue(Field field, Condition condition) {
        BigDecimal sum = BigDecimal.ZERO;
        for (ITableService iTableService : getTableServiceList()) {
            FieldValue sumFieldValue = iTableService.getSumFieldValue(field, condition);
            if (ObjectUtils.isNotNull(sumFieldValue) && sumFieldValue.isNotNull()) {
                sum.add(sumFieldValue.getBigDecimal());
            }
        }
        return new FieldValue(sum);
    }

    @Override
    public FieldValue getSumFieldValue(String fieldName, Condition condition) {
        BigDecimal sum = BigDecimal.ZERO;
        for (ITableService iTableService : getTableServiceList()) {
            FieldValue sumFieldValue = iTableService.getSumFieldValue(fieldName, condition);
            if (ObjectUtils.isNotNull(sumFieldValue) && sumFieldValue.isNotNull()) {
                sum.add(sumFieldValue.getBigDecimal());
            }
        }
        return new FieldValue(sum);
    }

    @Override
    public Field getPrimaryKeyField() {
        ITableService firstTableService = getFirstTableService();
        return firstTableService.getPrimaryKeyField();
    }

    @Override
    public List<Field> getFields() {
        ITableService firstTableService = getFirstTableService();
        return firstTableService.getFields();
    }

    @Override
    public Field getField(String name) {
        ITableService firstTableService = getFirstTableService();
        return firstTableService.getField(name);
    }

    @Override
    public Boolean containOp(RecordRow recordRow) {
        ITableService firstTableService = getFirstTableService();
        return firstTableService.containOp(recordRow);
    }

    @Override
    public ServiceOperateEnum getOp(RecordRow recordRow) {
        ITableService firstTableService = getFirstTableService();
        return firstTableService.getOp(recordRow);
    }

    @Override
    public AbstractService getServiceBean(String serviceName) {
        return getContext().getServiceBean(serviceName);
    }

    @Override
    public Boolean needDefaultNameField() {
        return false;
    }

    @Override
    public Context getContext() {
        return context;
    }

    @Override
    public Boolean isLazyLoadField() {
        return false;
    }

    @Override
    public FieldHashMap getUniqueFiled() {
        ITableService firstTableService = getFirstTableService();
        return firstTableService.getUniqueFiled();
    }

    @Override
    public Boolean hasRelationTable() {
        ITableService firstTableService = getFirstTableService();
        return firstTableService.hasRelationTable();
    }

    @Override
    public AbstractService getService() {
        return getFirstTableService().getService();
    }

    @Override
    public FieldValue getFieldValue(String fieldName, Integer id) {
        for (ITableService iTableService : getTableServiceList()) {
            FieldValue fieldValue = iTableService.getFieldValue(fieldName, id);
            if (ObjectUtils.isNotNull(fieldValue) && fieldValue.isNotNull()) {
                return fieldValue;
            }
        }
        return null;
    }

    @Override
    public FieldValue getFieldValue(String fieldName, Condition condition) {
        for (ITableService iTableService : getTableServiceList()) {
            FieldValue fieldValue = iTableService.getFieldValue(fieldName, condition);
            if (ObjectUtils.isNotNull(fieldValue) && fieldValue.isNotNull()) {
                return fieldValue;
            }
        }
        return null;
    }

    @Override
    public FieldValue getFieldValue(Field field, Object id) {
        for (ITableService iTableService : getTableServiceList()) {
            FieldValue fieldValue = iTableService.getFieldValue(field, id);
            if (ObjectUtils.isNotNull(fieldValue) && fieldValue.isNotNull()) {
                return fieldValue;
            }
        }
        return null;
    }

    @Override
    public FieldValue getFieldValue(Field field, Condition condition) {
        for (ITableService iTableService : getTableServiceList()) {
            FieldValue fieldValue = iTableService.getFieldValue(field, condition);
            if (ObjectUtils.isNotNull(fieldValue) && fieldValue.isNotNull()) {
                return fieldValue;
            }
        }
        return null;
    }

    @Override
    public void setFieldValue(String fieldName, Object value, Integer id) {
        for (ITableService iTableService : getTableServiceList()) {
            iTableService.setFieldValue(fieldName, value, id);
        }
    }

    @Override
    public void setFieldValue(String fieldName, Object value, Condition condition) {
        for (ITableService iTableService : getTableServiceList()) {
            iTableService.setFieldValue(fieldName, value, condition);
        }
    }

    @Override
    public void setFieldValue(Field field, Object value, Object id) {
        for (ITableService iTableService : getTableServiceList()) {
            iTableService.setFieldValue(field, value, id);
        }
    }

    @Override
    public void setFieldValue(Field field, Object value, Condition condition) {
        for (ITableService iTableService : getTableServiceList()) {
            iTableService.setFieldValue(field, value, condition);
        }
    }

    @Override
    public void updateNumberValue(RecordRow recordRow) {
        for (ITableService iTableService : getTableServiceList()) {
            iTableService.updateNumberValue(recordRow);
        }
    }

    @Override
    public void updateNumberValue(RecordRow recordRow, Integer id) {
        for (ITableService iTableService : getTableServiceList()) {
            iTableService.updateNumberValue(recordRow, id);
        }
    }

    @Override
    public void updateNumberValue(RecordRow recordRow, Condition condition) {
        for (ITableService iTableService : getTableServiceList()) {
            iTableService.updateNumberValue(recordRow, condition);
        }
    }

    @Override
    public void updateNumberValue(Field field, FieldValue value, Integer id) {
        for (ITableService iTableService : getTableServiceList()) {
            iTableService.updateNumberValue(field, value, id);
        }
    }

    @Override
    public void updateNumberValue(String fieldName, FieldValue value, Integer id) {
        for (ITableService iTableService : getTableServiceList()) {
            iTableService.updateNumberValue(fieldName, value, id);
        }
    }

    @Override
    public void updateNumberValue(Field field, Object value, Integer id) {
        for (ITableService iTableService : getTableServiceList()) {
            iTableService.updateNumberValue(field, value, id);
        }
    }

    @Override
    public void updateNumberValue(String fieldName, Object value, Integer id) {
        for (ITableService iTableService : getTableServiceList()) {
            iTableService.updateNumberValue(fieldName, value, id);
        }
    }

    @Override
    public void updateNumberValue(Field field, FieldValue value, Condition condition) {
        for (ITableService iTableService : getTableServiceList()) {
            iTableService.updateNumberValue(field, value, condition);
        }
    }

    @Override
    public void updateNumberValue(String fieldName, FieldValue value, Condition condition) {
        for (ITableService iTableService : getTableServiceList()) {
            iTableService.updateNumberValue(fieldName, value, condition);
        }
    }

    @Override
    public void updateNumberValue(Field field, Object value, Condition condition) {
        for (ITableService iTableService : getTableServiceList()) {
            iTableService.updateNumberValue(field, value, condition);
        }
    }

    @Override
    public void updateNumberValue(String fieldName, Object value, Condition condition) {
        for (ITableService iTableService : getTableServiceList()) {
            iTableService.updateNumberValue(fieldName, value, condition);
        }
    }

    private final TableServiceList tableServiceList = new TableServiceList();

    protected abstract void initTableService();

    @Override
    public TableServiceList getTableServiceList() {
        return tableServiceList;
    }

    @Override
    public void addTableService(ITableService tableService) {
        tableServiceList.add(tableService);
    }

    @Override
    public void onApplicationEvent(ApplicationEvent event) {
        if (event instanceof ApplicationReadyEvent) {
            initTableService();
        }
    }
}
